import 'dart:convert';
import 'dart:io';

import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_image_picker/model/file_upload_result.dart';
import 'package:flutter_image_picker/url.dart';

/// 上传成功的回调
typedef SuccessCallback = Function(String uploadFileUrl);

/// 上传失败的回调
typedef ErrorCallback = Function(String errorMsg);

/// 文件上传工具类
class HttpFileUtil {
  /// 发起文件上传请求
  static void fileUpload(SuccessCallback? callBack,
      {FormData? formData, ErrorCallback? errorCallBack}) async {
    _post(Url.fileUploadUrl, callBack,
        formData: formData, errorCallBack: errorCallBack);
  }

  /// POST请求
  static void _post(String url, SuccessCallback? callBack,
      {FormData? formData, ErrorCallback? errorCallBack}) async {
    String errorMsg = "";
    int statusCode;

    BaseOptions baseOptions;
    try {
      baseOptions = BaseOptions(
          baseUrl: Url.getBaseUrl(),
          connectTimeout: const Duration(milliseconds: 30000),
          receiveTimeout: const Duration(milliseconds: 30000),
          responseType: ResponseType.plain,
          contentType: "multipart/form-data; boundary=${formData?.boundary}",
          headers: {
            HttpHeaders.contentTypeHeader:
                "multipart/form-data; boundary=${formData?.boundary}",
          });
    } catch (exception) {
      if (kDebugMode) {
        print(exception);
      }
      return;
    }

    // 构建Dio请求客户端
    Dio dio = Dio(baseOptions);
    if (!kIsWeb) {
      // 添加Cookie拦截器
      dio.interceptors.add(CookieManager(CookieJar()));
    }
    if (!kIsWeb) {
      // 简单粗暴方式处理校验证书
      (dio.httpClientAdapter as IOHttpClientAdapter).onHttpClientCreate =
          (client) {
        client.badCertificateCallback =
            (X509Certificate cert, String host, int port) {
          return true;
        };
        return client;
      };
    }

    // 发起请求
    try {
      Response response;
      if (formData != null) {
        response = await dio.post(
          url,
          data: formData,
        );
      } else {
        response = await dio.post(url);
      }
      // 获取响应状态码
      statusCode = response.statusCode ?? -1;

      // 处理状态码错误
      if (statusCode < 0) {
        errorMsg = "网络请求错误，状态码:$statusCode";
        _handError(errorCallBack, errorMsg: errorMsg);
        return;
      }

      // 解析响应结果
      if (callBack != null) {
        var result = response.data.toString();
        if (kDebugMode) {
          print("返回数据：$result");
        }
        var data = json.decode(result);
        FileUploadResult resultData = FileUploadResult.fromJson(data);
        // 成功
        if (resultData.code == 1) {
          callBack(resultData.data ?? "");
        } else {
          // 失败
          _handError(errorCallBack, errorMsg: resultData.msg);
        }
      }
    } catch (exception) {
      // 解析失败
      String code = exception.toString();
      String errorString = code.contains("timed out") ? "请求超时" : "服务异常";
      _handError(errorCallBack, errorMsg: errorString);
    }
  }

  /// 异常处理
  static void _handError(ErrorCallback? errorCallback,
      {String? errorMsg = ""}) {
    if (errorCallback != null) {
      errorCallback(errorMsg!);
    }
    if (kDebugMode) {
      print("<net> errorMsg :$errorMsg");
    }
  }
}
